1.获取上传的文件
- request.FILES.get('file_name')
def upload_file(request):
if request.method == 'POST':
file_obj = request.FILES.get('img_file') # 获取上传文件
return render(request, 'upload_file.html')
2.获取上传文件的文件名+后缀
- request.FILES.get('file_name').name
def upload_file(request):
if request.method == 'POST':
file_obj = request.FILES.get('img_file')
file_name = file_obj.name # 获取上传文件的文件名+后缀
# 等价于
file_name = request.FILES.get('img_file').name # 获取上传文件的文件名+后缀
return render(request, 'upload_file.html')
3.获取上传文件的大小
- request.FILES.get('file_name').size
def upload_file(request):
if request.method == 'POST':
file_obj = request.FILES.get('img_file')
file_size = file_obj.size # 获取上传文件的大小
# 等价于
file_size = request.FILES.get('img_file').size # 获取上传文件的大小
return render(request, 'upload_file.html')
4..read()
- 一次性读取整个上传文件的内容,这个方法只适合于小文件
- 语法: request.FILES.get('file_name').read()
def upload_file(request):
if request.method == 'POST':
file_obj = request.FILES.get('img_file') # 获取上传文件
file_name = file_obj.name # 获取上传文件的文件名+后缀
with open(file_name, 'wb') as f:
all_data = file_obj.read() # 一次性读取整个上传文件的内容
f.write(all_data)
return HttpResponse('上传成功')
return render(request, 'upload_file.html')
5..chunks()
- 按块返回上传文件的内容,通过在for循环中进行迭代,可以将大文件按照块写入服务器中
- 注意: 这个方法和直接循环文件对象是差不多的,不同在于.chunks()方法是一块一块的读取数据,而直接循环文件对象是一行一行的读取数据
- 语法: request.FILES.get('file_name').chunks()
def upload_file(request):
if request.method == 'POST':
file_obj = request.FILES.get('img_file') # 获取上传文件
file_name = file_obj.name # 获取上传文件的文件名+后缀
with open(file_name, 'wb') as f:
for line in file_obj.chunks(): # 一块一块的读取并且写入
f.write(line)
return HttpResponse('上传成功')
return render(request, 'upload_file.html')
6..multiple_chunks(chunk_size=None)
- 根据上传文件的大小,返回True或者False,当上传文件大于2.5M(默认为2.5M,可以调整)时,该方法返回True,否则返回False
- 可以根据.multiple_chunks()方法来选择选用.read()方法读取还是采用.chunks()方法
- 语法: request.FILES.get('file_name').multiple_chunks()
def upload_file(request):
if request.method == 'POST':
file_obj = request.FILES.get('img_file') # 获取上传文件
file_name = file_obj.name # 获取上传文件的文件名+后缀
with open(file_name, 'wb') as f:
if file_obj.multiple_chunks(): # 判断上传文件是否超过了2.5M
for line in file_obj.chunks(): # 一块一块的读取并且写入
f.write(line)
else:
all_data = file_obj.read() # 一次性读取整个上传文件的内容
f.write(all_data)
return HttpResponse('上传成功')
return render(request, 'upload_file.html')
7.使用form表单上传文件的例子
- 注意: 如果表单中带有要上传的文件,那么一定要修改表单中的 enctype="multipart/form-data"
- enctype 参数说明:
- application/x-www-form-urlencoded -> 一般用于提交不带文件的表单 -> 默认值
- multipart/form-data -> 一般用于提交带文件的表单
- enctype 参数 和 Content-Type 的关系
- enctype 参数其实就是修改请求头中的 Content-Type 参数,而 Content-Type 参数就是让浏览器告诉服务器这次请求数据的格式是什么
- Content-Type参数的默认值和enctype参数一样都是 urlencoded
- 注意事项:
- 如果表单中没有上传文件,那么使用默认值提交就可以(即: 无需修改enctype参数),Django会将表单提交过来的数据放到 request.GET/POST 中
- 如果表单中有上传文件,那么一定要修改表单中的 enctype="multipart/form-data",Django会将上传文件以外的数据放到 request.GET/POST 中,将上传文件放到 reques.FILES 中
- 如果表单中有上传文件,且没有修改 enctype="multipart/form-data",Django会将表单提交过来的数据放到 request.GET/POST 中,那么通过 request.GET/POST.get('file_name') 获取到的只是上传文件的文件名+后缀,不是一个文件对象
# views.py
def upload_file(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
file_obj = request.FILES.get('img_file') # 获取上传文件
file_name = file_obj.name # 获取上传文件的文件名+后缀
with open(file_name, 'wb') as f:
# for line in file_obj: # 一行一行的读取并且写入
# 等价于
for line in file_obj.chunks(): # 一块一块的读取并且写入
f.write(line)
return HttpResponse('上传成功')
return render(request, 'upload_file.html')
# xxx.html
<form action="" method=post enctype="multipart/form-data">
{% csrf_token %}
<p><input type="text" name="username" id="" placeholder="用户名"></p>
<p><input type="password" name="password" id="" placeholder='密码'></p>
<p><input type="file" name="img_file" id=""></p>
<input type="submit" value="提交">
</form>
8.将上传文件保存到 media 文件夹中
- 将上传文件保存到 media 文件夹中的前提是配置了media
- 使用 settings.py 中 media 文件夹路径的配置项进行上传文件保存路径的拼接
# views.py
from django.shortcuts import render, HttpResponse
from upper_bunken import settings
import os
def upload_file(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
file_obj = request.FILES.get('img_file') # 获取上传文件
file_name = file_obj.name # 获取上传文件的文件名+后缀
path = os.path.join(settings.MEDIA_ROOT, file_name) # 使用 settings.py 中的 media 配置项的路径进行拼接
# 等同于
# path = 'media/' + file_name # 不建议这么写:
# 一、因为当 media 文件夹被改动了,那么这里的路径也需要改动,但是使用上面的方法就无需改动,只要修改 settings.py 中的 media 配置项就可以了
# 二、因为在 linux 中路径分割符是 \,而不是/,如果在linux下运行有可能会报错
with open(path, 'wb') as f:
# for line in file_obj: # 一行一行的读取并且写入
# 等价于
for line in file_obj.chunks(): # 一块一块的读取并且写入
f.write(line)
return HttpResponse('上传成功')
return render(request, 'upload_file.html')
# xxx.html
<form action="" method=post enctype="multipart/form-data">
{% csrf_token %}
<p><input type="text" name="username" id="" placeholder="用户名"></p>
<p><input type="password" name="password" id="" placeholder='密码'></p>
<p><input type="file" name="img_file" id=""></p>
<input type="submit" value="提交">
</form>
8.使用Ajax上传文件的例子
- 注意事项:Ajax上传文件的注意事项和Form表单差不多,都需要通过修改某些参数后才能进行提交
# views.py
def upload_file(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
file_obj = request.FILES.get('img_file') # 获取上传文件
file_name = file_obj.name # 获取上传文件的文件名+后缀
with open(file_name, 'wb') as f:
# for line in file_obj: # 一行一行的读取并且写入
# 等价于
for line in file_obj.chunks(): # 一块一块的读取并且写入
f.write(line)
return HttpResponse('上传成功')
return render(request, 'upload_file.html')
- 写法一 -> 推荐使用
# xxx.html
<div>
{% csrf_token %}
<p><input type="text" name="username" id="username" placeholder="用户名"></p>
<p><input type="password" name="password" id="password" placeholder='密码'></p>
<p><input type="file" name="img_file" id="img_file"></p>
<button id="btn">提交</button>
</div>
<script type="text/javascript">
$(function () {
$('#btn').click(function () {
// 将数据添加到 FormData 里面
var formData = new FormData();
formData.append('username', $('#username').val());
formData.append('password', $('#password').val());
formData.append('csrfmiddlewaretoken', $("[name='csrfmiddlewaretoken']").val());
formData.append('img_file', $('#img_file')[0].files[0]);
$.ajax({
url: '/upload_file/',
type: "POST",
processData: false, // 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
data: formData,
success: function (data) {
console.log(data)
}
})
})
})
</script>
- 写法二
- 有点问题: 就算Ajax设置了POST请求,但是在发送的时候还是GET请求
# xxx.html
<form id="upload-form">
{% csrf_token %}
<p><input type="text" name="username" id="username" placeholder="用户名"></p>
<p><input type="password" name="password" id="password" placeholder='密码'></p>
<p><input type="file" name="img_file" id="img_file"></p>
<button id="btn">提交</button>
</form>
<script type="text/javascript">
$(function () {
$('#btn').click(function () {
// 将数据添加到 FormData 里面
var form = $('#upload-form')[0];
var formData = new FormData(form);
$.ajax({
url: '/upload_file/',
type: "POST",
processData: false, // 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
data: formData,
success: function (data) {
console.log(data)
}
})
})
})
</script>
← Cookie Django 日志配置 →